#include "network/epoll_server.h"
#include <iostream>
#include <cstring>
#include <cerrno>
#include <cassert>

namespace network {

// 静态成员初始化
std::atomic<uint64_t> Connection::nextId_(1);

// Connection 实现
Connection::Connection(int sockfd, const struct sockaddr_in& addr)
    : sockfd_(sockfd), addr_(addr), id_(nextId_++) {
}

Connection::~Connection() {
    if (sockfd_ >= 0) {
        close(sockfd_);
        sockfd_ = -1;
    }
}

std::string Connection::getIp() const {
    char ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &addr_.sin_addr, ip, sizeof(ip));
    return ip;
}

int Connection::getPort() const {
    return ntohs(addr_.sin_port);
}

void Connection::send(const std::string& message) {
    std::lock_guard<std::mutex> lock(mutex_);
    outputBuffer_ += message;
    
    // 尝试立即发送
    int ret = ::send(sockfd_, outputBuffer_.c_str(), outputBuffer_.size(), 0);
    if (ret > 0) {
        outputBuffer_ = outputBuffer_.substr(ret);
    }
}

void Connection::handleRead() {
    char buf[4096];
    int nbytes;
    
    while ((nbytes = ::recv(sockfd_, buf, sizeof(buf), 0)) > 0) {
        inputBuffer_.append(buf, nbytes);
    }
    
    if (nbytes == 0) {
        // 客户端关闭连接
        handleClose();
        return;
    } else if (nbytes < 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            std::cerr << "recv error: " << strerror(errno) << std::endl;
            handleClose();
            return;
        }
    }
    
    // 处理完整的消息
    if (!inputBuffer_.empty() && messageCallback_) {
        messageCallback_(shared_from_this(), inputBuffer_);
        inputBuffer_.clear();
    }
}

void Connection::handleWrite() {
    std::lock_guard<std::mutex> lock(mutex_);
    if (outputBuffer_.empty()) {
        return;
    }
    
    int ret = ::send(sockfd_, outputBuffer_.c_str(), outputBuffer_.size(), 0);
    if (ret > 0) {
        outputBuffer_ = outputBuffer_.substr(ret);
    } else if (ret < 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            std::cerr << "send error: " << strerror(errno) << std::endl;
            handleClose();
        }
    }
}

void Connection::handleClose() {
    if (closeCallback_) {
        closeCallback_(shared_from_this());
    }
}

// EpollServer 实现
EpollServer::EpollServer(int port, int threadNum)
    : port_(port), listenFd_(-1), epollFd_(-1), 
      running_(false), threadNum_(threadNum) {
}

EpollServer::~EpollServer() {
    stop();
}

bool EpollServer::initSocket() {
    listenFd_ = socket(AF_INET, SOCK_STREAM, 0);
    if (listenFd_ < 0) {
        std::cerr << "创建socket失败: " << strerror(errno) << std::endl;
        return false;
    }
    
    // 设置地址重用
    int opt = 1;
    if (setsockopt(listenFd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
        std::cerr << "设置SO_REUSEADDR失败: " << strerror(errno) << std::endl;
        close(listenFd_);
        return false;
    }
    
    // 设置非阻塞
    setNonBlocking(listenFd_);
    
    // 绑定地址
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port_);
    
    if (bind(listenFd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        std::cerr << "绑定端口" << port_ << "失败: " << strerror(errno) << std::endl;
        close(listenFd_);
        return false;
    }
    
    // 开始监听
    if (listen(listenFd_, SOMAXCONN) < 0) {
        std::cerr << "监听失败: " << strerror(errno) << std::endl;
        close(listenFd_);
        return false;
    }
    
    // 创建epoll实例
    epollFd_ = epoll_create1(0);
    if (epollFd_ < 0) {
        std::cerr << "创建epoll实例失败: " << strerror(errno) << std::endl;
        close(listenFd_);
        return false;
    }
    
    // 将监听socket添加到epoll
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = listenFd_;
    if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, listenFd_, &ev) < 0) {
        std::cerr << "添加监听socket到epoll失败: " << strerror(errno) << std::endl;
        close(epollFd_);
        close(listenFd_);
        return false;
    }
    
    std::cout << "服务器初始化成功，监听端口: " << port_ << std::endl;
    return true;
}

void EpollServer::setNonBlocking(int sockfd) {
    int flags = fcntl(sockfd, F_GETFL, 0);
    if (flags < 0) {
        std::cerr << "fcntl F_GETFL失败: " << strerror(errno) << std::endl;
        return;
    }
    
    if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
        std::cerr << "fcntl F_SETFL O_NONBLOCK失败: " << strerror(errno) << std::endl;
    }
}

void EpollServer::start() {
    if (running_) {
        return;
    }
    
    if (!initSocket()) {
        return;
    }
    
    running_ = true;
    
    // 创建工作线程
    for (int i = 0; i < threadNum_; i++) {
        threads_.emplace_back(&EpollServer::workerThread, this);
    }
    
    std::cout << "服务器启动成功，工作线程数: " << threadNum_ << std::endl;
}

void EpollServer::stop() {
    running_ = false;
    
    // 等待所有工作线程结束
    for (auto& thread : threads_) {
        if (thread.joinable()) {
            thread.join();
        }
    }
    threads_.clear();
    
    // 关闭所有连接
    std::lock_guard<std::mutex> lock(connectionsMutex_);
    for (auto& pair : connections_) {
        pair.second->handleClose();
    }
    connections_.clear();
    
    // 关闭epoll和监听socket
    if (epollFd_ >= 0) {
        close(epollFd_);
        epollFd_ = -1;
    }
    
    if (listenFd_ >= 0) {
        close(listenFd_);
        listenFd_ = -1;
    }
    
    std::cout << "服务器已停止" << std::endl;
}

void EpollServer::workerThread() {
    struct epoll_event events[MAX_EVENTS];
    
    while (running_) {
        int nfds = epoll_wait(epollFd_, events, MAX_EVENTS, 1000); // 超时1秒
        
        if (nfds < 0) {
            if (errno != EINTR) {
                std::cerr << "epoll_wait错误: " << strerror(errno) << std::endl;
                break;
            }
            continue;
        }
        
        for (int i = 0; i < nfds; i++) {
            if (events[i].data.fd == listenFd_) {
                // 新连接到达
                handleNewConnection();
            } else {
                // 处理已有连接的事件
                handleEvent(events[i]);
            }
        }
    }
}

void EpollServer::handleNewConnection() {
    struct sockaddr_in addr;
    socklen_t addrLen = sizeof(addr);
    
    int connfd = accept(listenFd_, (struct sockaddr*)&addr, &addrLen);
    if (connfd < 0) {
        std::cerr << "accept错误: " << strerror(errno) << std::endl;
        return;
    }
    
    // 设置非阻塞
    setNonBlocking(connfd);
    
    // 添加到epoll
    struct epoll_event ev;
    ev.events = EPOLLIN | EPOLLET; // 边缘触发模式
    ev.data.fd = connfd;
    if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, connfd, &ev) < 0) {
        std::cerr << "添加新连接到epoll失败: " << strerror(errno) << std::endl;
        close(connfd);
        return;
    }
    
    // 创建连接对象
    auto conn = std::make_shared<Connection>(connfd, addr);
    
    // 设置回调函数
    if (messageCallback_) {
        conn->setMessageCallback(messageCallback_);
    }
    
    conn->setCloseCallback([this](std::shared_ptr<Connection> conn) {
        // 在epoll中移除
        epoll_ctl(epollFd_, EPOLL_CTL_DEL, conn->getFd(), nullptr);
        
        // 从连接表中移除
        std::lock_guard<std::mutex> lock(connectionsMutex_);
        connections_.erase(conn->getFd());
        
        // 调用用户设置的关闭回调
        if (closeCallback_) {
            closeCallback_(conn);
        }
    });
    
    // 添加到连接表
    {
        std::lock_guard<std::mutex> lock(connectionsMutex_);
        connections_[connfd] = conn;
    }
    
    // 调用用户设置的连接回调
    if (connectionCallback_) {
        connectionCallback_(conn);
    }
    
    std::cout << "新连接: " << conn->getIp() << ":" << conn->getPort() 
              << ", ID: " << conn->getId() << std::endl;
}

void EpollServer::handleEvent(struct epoll_event& event) {
    int fd = event.data.fd;
    
    std::shared_ptr<Connection> conn;
    {
        std::lock_guard<std::mutex> lock(connectionsMutex_);
        auto it = connections_.find(fd);
        if (it == connections_.end()) {
            // 连接已关闭
            return;
        }
        conn = it->second;
    }
    
    if (event.events & EPOLLIN) {
        // 可读事件
        conn->handleRead();
    }
    
    if (event.events & EPOLLOUT) {
        // 可写事件
        conn->handleWrite();
    }
    
    if (event.events & (EPOLLHUP | EPOLLERR)) {
        // 错误或挂起事件
        std::cerr << "连接出错或挂起: " << conn->getIp() << ":" << conn->getPort() << std::endl;
        conn->handleClose();
    }
}

} // namespace network 